package com.spider.im.chat.server;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;


import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
        private final AtomicInteger connectionsCount;

        public TextWebSocketFrameHandler(AtomicInteger connectionsCount) {
            this.connectionsCount = connectionsCount;
        }

        @Override
        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
            super.handlerAdded(ctx);
            connectionsCount.incrementAndGet();
            log.info("Client connected. Total connections: {}" , connectionsCount.get());
        }

        @Override
        public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
            super.handlerRemoved(ctx);
            connectionsCount.decrementAndGet();
            log.info("Client disconnected. Total connections: {}" , connectionsCount.get());
        }
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        log.info("新客户端连接：{}" , ctx.channel().remoteAddress());
        String requestJson = "Welcome to the server!";
        ctx.writeAndFlush(new TextWebSocketFrame(requestJson));
    }
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
            // 检查握手是否成功
//            if (!ctx.channel().isActive() || !ctx.channel().isOpen()) {
//                log.warn("Handshake not completed or connection is closed. Closing the channel.");
//                ctx.close();
//                return;
//            }
//            String requestJson = msg.text();
//            log.info(String.format("%s received %s", ctx.channel(), requestJson));
//
//            messageService.processRequest(requestJson, ctx.channel());

            ctx.channel().writeAndFlush(new TextWebSocketFrame("接收到消息"));


        }

    /**
     * 当用户事件触发时调用此方法
     * 主要用于处理IdleStateEvent事件，以确定何时通道由于不活动而需要关闭
     *
     * @param ctx 通道处理上下文，提供了访问通道、管道等信息的能力
     * @param evt 触发的事件对象，本方法中主要关注IdleStateEvent
     * @throws Exception 如果处理事件时发生错误，可以抛出异常
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        // 判断事件是否为IdleStateEvent类型
        if (evt instanceof IdleStateEvent idleStateEvent) {
            try {
                // 判断是否为 ALL_IDLE 状态
                if (idleStateEvent.state() == IdleState.ALL_IDLE) {
                    // 如果是ALL_IDLE状态，记录警告日志并关闭连接
                    log.warn("Closing connection due to inactivity - channelId: {}, state: {}",
                            ctx.channel().id(), idleStateEvent.state());
                    ctx.close(); // 关闭连接
                } else {
                    // 如果不是ALL_IDLE状态，调用方法处理其他状态的事件
                    handleNonIdleEvent(ctx, idleStateEvent);
                }
            } catch (Exception e) {
                // 异常处理，记录错误日志
                log.error("An error occurred while handling IdleStateEvent for channel {}: {}",
                        ctx.channel().id(), e.getMessage(), e);
            }
        } else {
            // 如果事件不是IdleStateEvent类型，调用父类方法处理
            super.userEventTriggered(ctx, evt);
        }
    }

    private void handleNonIdleEvent(ChannelHandlerContext ctx, IdleStateEvent idleStateEvent) {
        try {
            log.debug("Handling non-ALL_IDLE event - channelId: {}, state: {}",
                    ctx.channel().id(), idleStateEvent.state());
            super.userEventTriggered(ctx, idleStateEvent);
        } catch (Exception e) {
            log.error("An error occurred while handling non-ALL_IDLE event for channel {}: {}",
                    ctx.channel().id(), e.getMessage(), e);
        }
    }


    @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

            log.error("Exception occurred during handshake or communication: ", cause);
            ctx.close();
        }
    }